Release v3.8.0#1997
Conversation
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Integrated into release/v3.8.0
There was a problem hiding this comment.
Code Review
This pull request introduces support for custom project IDs in the Gemini CLI transport, enabling better configuration for managed projects. It also standardizes provider icon rendering across the dashboard and CLI tool components by migrating from local image files to a centralized ProviderIcon component using SVG assets. Additionally, the project version has been bumped to 3.8.0. I have no feedback to provide.
CI Coverage Report
Coverage artifact was not available for this run. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1985af8965
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| codexOpenaiStoreEnabled: connection.providerSpecificData?.openaiStoreEnabled === true, | ||
| consoleApiKey: existingConsoleApiKey, | ||
| ccCompatibleContext1m: ccRequestDefaults.context1m, | ||
| geminiProjectId: (connection.providerSpecificData?.projectId as string) || "", |
There was a problem hiding this comment.
Initialize Gemini project field from persisted connection projectId
The edit modal populates geminiProjectId only from providerSpecificData.projectId, but existing Gemini OAuth connections commonly store their active project in top-level connection.projectId; when users open the modal and save unrelated changes, the blank field causes updates.projectId to be written as null, silently clearing a previously valid project and breaking requests in cases where loadCodeAssist refresh is unavailable or fails.
Useful? React with 👍 / 👎.
| if (credentials.accessToken) { | ||
| // Refresh the project ID via loadCodeAssist (cached for 30s) only when project not provided | ||
| // and credentials have an access token | ||
| if (!envelope.project && credentials.accessToken) { |
There was a problem hiding this comment.
Keep project refresh for OAuth-backed Gemini requests
This change skips refreshProject whenever envelope.project is already non-empty, which includes stale credentials.projectId values loaded from stored OAuth state; previously the executor always refreshed via loadCodeAssist, so stale/broken stored project IDs were corrected before dispatch, but now those requests are sent with the stale project and can fail with Cloud Code permission errors.
Useful? React with 👍 / 👎.
Add Linux certificate management via update-ca-certificates for Docker support. Skip sudo password validation when running as root, matching the existing cli-tools route behavior.
… identity contamination (#1989)
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: dda5269e77
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| formData.codexOpenaiStoreEnabled === true; | ||
| } | ||
| if (isGeminiCli) { | ||
| updates.providerSpecificData.projectId = formData.geminiProjectId.trim() || undefined; |
There was a problem hiding this comment.
Clear Gemini projectId key instead of sending undefined
When the Gemini project field is cleared, this writes undefined, and JSON.stringify omits that property from the PUT payload. The server then merges providerSpecificData with existing values, so the old providerSpecificData.projectId persists; with this commit’s executor fallback to credentials.providerSpecificData.projectId, Gemini CLI requests continue using the stale project even after users try to clear it, which can keep Cloud Code requests failing until OAuth is reconnected.
Useful? React with 👍 / 👎.
- Replace || "Unknown" fallbacks with || null in usage.ts (GLM + Claude legacy) - Add plan extraction to Claude OAuth mapTokens (account_tier > plan > subscription_type > billing.plan) - Add unit tests for plan extraction and Provider Limits badge resolution
The original fix replaced || "Unknown" with || null for GLM and Claude legacy (non-OAuth) paths. Per user clarification, "Unknown" is a valid display fallback when no plan data exists — null-based fallbacks caused the Provider Limits dashboard to show no badge rather than a clear "Unknown" indicator. Revert only the usage.ts changes. Claude OAuth mapTokens plan extraction (claude.ts) and the associated tests remain unchanged.
Turbopack resolveAlias (@/mitm/manager → manager.stub.ts) was designed
for build-time safety but Next.js applies aliases to ALL imports —
including dynamic ones. This caused await import("@/mitm/manager") at
runtime to load the stub, which silently returned fake {running: true}
without spawning the MITM proxy. The UI showed "MITM proxy started"
but nothing was actually running.
Fix introduces a two-path design:
- @/mitm/manager → stub (build-time, safe for Turbopack)
- @/mitm/manager.runtime → real manager (runtime, bypasses alias)
Route handlers now dynamic-import from manager.runtime, which
re-exports from ./manager and does NOT match the alias pattern.
Additional fixes:
- Make stub throw explicit errors at runtime so misconfiguration is
immediately visible instead of silently faking success
- Add server.cjs to outputFileTracingIncludes (NFT trace) and Dockerfile
COPY so the MITM server binary exists in standalone/Docker output
Integrated into release/v3.8.0
Integrated into release/v3.8.0
…imits (#2030) Integrated into release/v3.8.0
Integrated into release/v3.8.0
|
|
||
| return uuidV4FromHash( | ||
| createHash("sha256") | ||
| .update("account:" + seed) |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 72d0e1ff1b
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| sessionId: "", // safety-net redirect doesn't have session context | ||
| forceLiveComboTest: false, | ||
| forcedConnectionId: null, | ||
| allowedConnectionIds: null, | ||
| comboStepId: null, | ||
| comboExecutionKey: null, |
There was a problem hiding this comment.
Preserve combo target metadata during auto-combo redirect
When resolveModelOrError() returns a combo (for example via alias-to-auto/* resolution), this redirect path drops the per-step routing context by hardcoding forcedConnectionId, allowedConnectionIds, comboStepId, and comboExecutionKey to null/empty values instead of forwarding target and the current runtime context. That lets combo steps execute on arbitrary accounts rather than their pinned connection and breaks per-step execution tracing/session-aware behavior for redirected combos.
Useful? React with 👍 / 👎.
| settings: {}, | ||
| allCombos: [], |
There was a problem hiding this comment.
Pass real combo context when redirecting to handleComboChat
The redirect path invokes handleComboChat with settings: {} and allCombos: [] instead of the DB-backed values used in the main combo flow, so redirected combos cannot reliably resolve nested combo references or strategy config (notably context-relay/cascade behavior). This only affects requests that enter combo flow through the new redirect, which makes behavior inconsistent with direct combo requests.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 321f6070ac
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| return Response.json( | ||
| { text: data?.data?.text || data?.text || "" }, | ||
| { headers: { "Access-Control-Allow-Origin": getCorsOrigin() } } | ||
| ); |
There was a problem hiding this comment.
Fail KIE transcription when createTask returns no task id
When the KIE createTask call succeeds at HTTP level but returns an error payload (no taskId), this branch still returns 200 with an empty text, so callers treat a failed transcription as successful output. This is a data-corruption path for any provider-side validation/runtime failure that is encoded in JSON rather than a non-2xx status.
Useful? React with 👍 / 👎.
| const urls = Array.isArray(resultJson?.resultUrls) | ||
| ? (resultJson.resultUrls as string[]) | ||
| : Array.isArray(resultJson?.videoUrls) | ||
| ? (resultJson.videoUrls as string[]) | ||
| : Array.isArray(response.resultUrls) | ||
| ? (response.resultUrls as string[]) | ||
| : []; |
There was a problem hiding this comment.
Parse single-url KIE video results
This normalizer only accepts array fields (resultUrls/videoUrls) and drops common singleton fields like resultUrl or url. For successful KIE jobs that return a single URL, the handler emits a success response with an empty data array, which breaks clients expecting a generated video despite upstream success.
Useful? React with 👍 / 👎.
- Add centralized antigravityIdentity service (sessionId, machineId, requestId) - Switch User-Agent to Electron/Chrome desktop format - Reorder upstream URLs: sandbox first, production last - Add runtime headers: x-client-name, x-client-version, x-machine-id, x-vscode-sessionid, x-goog-user-project - Add 403 retry without x-goog-user-project header - Add generation defaults (topK=40, topP=1.0, maxOutputTokens guard) - Strip cache_control from Claude requests recursively - Enterprise/consumer routing via userAgent field (jetski vs antigravity) - Update envelope field order and add enabledCreditTypes - MITM proxy: support multiple target hosts - Version: semver comparison with pickNewestVersion(), bump fallback to 4.1.33 - Update all affected tests
Dumps outgoing headers (with masked Authorization) and envelope structure (fieldOrder, project, requestId, userAgent, requestType, enabledCreditTypes, sessionId, generationConfig) at debug level for production verification of identity overhaul.
…its max_tokens Real Antigravity client does not send maxOutputTokens when the user hasn't specified it — the Cloud Code server decides the output limit. OmniRoute was incorrectly injecting a capped default from model specs, which caused thinking models to return empty content with low limits.
Integrated into release/v3.8.0
Integrated into release/v3.8.0
…2061) Integrated into release/v3.8.0
Integrated into release/v3.8.0
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: fc84e5a34a
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| const audioRes = await fetch(audioUrl); | ||
| return audioStreamResponse(audioRes); |
There was a problem hiding this comment.
Preserve upstream error when fetching KIE audio result URL
When KIE returns an audioUrl, this branch streams it with audioStreamResponse without checking audioRes.ok. If that signed URL is expired or forbidden (for example 403/404), audioStreamResponse still forces HTTP 200, so clients get a false-success response with non-audio error content and cannot reliably detect generation failure. The same pattern is repeated in pollKieAudioResult, so both immediate and polled KIE flows are affected.
Useful? React with 👍 / 👎.
…n Antigravity provider
… audio transcription CORS regression - Restored default adaptive thinking injection for non-Haiku Claude Code models when explicit client headers are omitted. - Updated Claude OAuth unit tests to accurately account for dynamic cliUserID property injection in mapped credentials. - Fixed module resolution regression in audio transcription handler caused by missing getCorsOrigin utility.
|



[3.8.0] — 2026-05-06
✨ New Features
🐛 Bug Fixes
🔒 Security
🧹 Chores & Maintenance
@lobehub/iconsweb fonts (chore(providers): prune redundant provider icon assets #1992)[3.7.9] — 2026-05-03
✨ New Features
feat(docs): integrate multi-page documentation into OmniRoute dashboard (feat(docs): integrate multi-page documentation into OmniRoute dashboard — Closes #1958 #1969)
feat(settings): add request body limit setting (feat(settings): add request body limit setting #1968)
feat(auth): add Gemini CLI OAuth client secret default (fix: add default Gemini CLI OAuth client secret #1974)
feat(models): expose models.dev context windows in /v1/models (fix(api): expose models.dev context windows in /v1/models #1972)
feat(compression): major upgrade to Caveman and RTK compression pipelines (feat(compression): atualização Caveman #1876, feat(compression): RTK compression roadmap #1889):
feat(provider): update Jina AI model catalog to support Embeddings and Rerank natively (chore(provider): Update Jina AI model catalog #1874 — thanks @backryun)
feat(provider): add NanoGPT image generation provider (feat(image-gen): add NanoGPT image generation provider #1899 — thanks @Aculeasis)
feat(ui): move proxy configuration to dedicated System → Proxy page (feat(proxy): move proxy configuration to dedicated System → Proxy page #1907 — thanks @oyi77)
feat(ui): add K/M/B/T cost shortener utility (feat: add K/M/B/T cost shortener to prevent UI overflow #1902 — thanks @oyi77)
feat(providers): implement bulk paste for extra API keys (feat(providers): implement bulk paste for extra API keys #1916 — thanks @0xtbug)
feat(analytics): usage history API key backfill + dark mode pricing (fix(analytics): robust model pricing resolution, dark mode charts and SQL aggregation fixes #1896 — thanks @Gi99lin)
feat(logs): show RTK and Caveman compression token savings accurately in request log UI (feat(logs): show compression tokens in request log UI #1923 — thanks @emdash)
feat(routing): auto-skip exhausted quota accounts (Issue [Feature] Skip (Codex) accounts that have the weekly or 5h quota exhausted #1952)
feat(docs): docs site overhaul (Feat/docs site overhaul #1976 — thanks @oyi77)
feat(db): consolidate all database settings into SystemStorageTab (closes [RFC] Database Performance Optimization - User-Configurable Aggregation & Cleanup #1935) (feat(db): consolidate all database settings into SystemStorageTab (closes #1935) #1947 — thanks @oyi77)
feat(sse): codex 429 mid-task failover with account rotation (feat(sse): codex 429 mid-task failover with account rotation #1888 — thanks @smartenok-ops)
feat(auto-assessment): add auto-assessment engine for combo self-healing (feat: Auto-Assessment and Self-Healing Combo Engine #1918 — thanks @oyi77)
feat(usage): DeepSeek V4 native cache token extraction (feat(usage): DeepSeek V4 native cache token extraction #1930 — thanks @smartenok-ops)
feat(cost): enhance cost formatting and add Codex GPT-5.5 pricing support (feat: enhance cost formatting and add Codex GPT-5.5 pricing support #1944 — thanks @JxnLexn)
🐛 Bug Fixes
unsafe-evalin productionscript-srcto fix unresponsive Onboarding button (fixes [BUG] Onboarding button unresponsive after upgrade from 2.x to 3.x — CSP blocks eval #1883)prompt_cache_retentioninBaseExecutorto prevent upstream 400 errors from strict endpoints like droid/gemini-2-pro (fixes [BUG] Unsupported parameter: prompt_cache_retention on droid factory #1884)isOpendependency inEditConnectionModalstate sync to ensuremaxConcurrentis properly hydrated when reopening the modal (fixes [BUG] Account Concurrency Cap Label show error when reopen #1859)normalizeCodexTools— preventsMissing required parameter: tools[0].nameupstream errors ([BUG] codex Missing required parameter: 'tools[0].name #1914 — thanks @tranduykhanh030)properties: {}into zero-argument MCP tool schemas during Anthropic→OpenAI translation — prevents 400 errors from OpenAI strict schema validation ([BUG] Anthropic to OpenAI translation fails for zero-argument MCP tools (400: object schema missing properties) #1898 — thanks @bryceIT)🔄 Updates
📝 Documentation
🏆 Release Attribution & Retroactive Credits
Tests